home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
sos3-2.lha
/
src
/
agg
/
Array_scp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-23
|
22KB
|
613 lines
#line 1 "/fzi/prost/stone/SOS3-2/src/agg/Array.c"
/* --------------------------------------------------------------------------
* Copyright 1992 by Forschungszentrum Informatik (FZI)
*
* You can use and distribute this software under the terms of the licence
* you should have received along with this program.
* If not or if you want additional information, write to
* Forschungszentrum Informatik, "STONE", Haid-und-Neu-Strasse 10-14,
* D-7500 Karlsruhe 1, Germany.
* --------------------------------------------------------------------------
*/
// **************************************************************************
// Module Array 30/08/89 Bernhard Schiefer (bs)
// 26/06/90 (bs)
// **************************************************************************
// implements methods of classes: Array
// **************************************************************************
#include "sys.h"
#include "knl_err.h"
#include "agg_err.h"
#include "trc_agg.h"
#include "agg_sos.h"
// **************************************************************************
sos_Int _sos_Object_Array::element_size (sos_Typed_id &_tpid)
// **************************************************************************
{
return SOS_TYPED_ID_SIZE; // as long as only references are stored!
// otherwise get the size of the Array's
// element type from the schema
} // ** element_size **
// **************************************************************************
void _sos_Object_Array::local_initialize (sos_Object_Array arr)
// **************************************************************************
{
T_PROC ("sos_Object_Array::local_initialize");
TT (agg_H, T_ENTER);
Index c = arr.get_top_index() - arr.get_bottom_index() + 1;
if (c<=0)
arr.set_address (0);
else
arr.set_address (arr.container().allocate(c*arr.element_size()));
TT (agg_H, T_LEAVE);
} // ** local_initialize **
// **************************************************************************
void _sos_Object_Array::local_finalize (sos_Object_Array arr)
// **************************************************************************
{
T_PROC ("sos_Object_Array::local_finalize");
TT (agg_H, T_ENTER);
sos_Int length = arr.card()*arr.element_size();
if (length > 0)
arr.container().deallocate (arr.get_address(), length);
TT (agg_H, T_LEAVE);
} // ** local_finalize **
// **************************************************************************
Index _sos_Object_Array::get_bottom (sos_Typed_id &_tpid)
// **************************************************************************
{
T_PROC ("sos_Object_Array::get_bottom");
TT (agg_H, T_ENTER);
Index b = sos_Object_Array::make(_tpid,this).get_bottom_index();
TT (agg_H, T_LEAVE; TI (b));
return b;
} // ** get_bottom **
// **************************************************************************
Index _sos_Object_Array::get_top (sos_Typed_id &_tpid)
// **************************************************************************
{
T_PROC ("sos_Object_Array::get_bottom");
TT (agg_H, T_ENTER);
Index t = sos_Object_Array::make(_tpid,this).get_top_index();
TT (agg_H, T_LEAVE; TI (t));
return t;
} // ** get_top **
// **************************************************************************
sos_Object _sos_Object_Array::get_nth (sos_Typed_id &_tpid,Index pos)
// **************************************************************************
{
T_PROC ("sos_Object_Array::get_nth");
TT (agg_H, T_ENTER; TI (pos));
if ((pos < sos_Object_Array::make(_tpid,this).get_bottom()) OR (pos > sos_Object_Array::make(_tpid,this).get_top()))
{ err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::get_nth", FALSE);
TT (agg_H, T_LEAVE );
return (NO_OBJECT);
}
sos_Offset act_pos = sos_Object_Array::make(_tpid,this).get_address() +
((pos - sos_Object_Array::make(_tpid,this).get_bottom()) * sos_Object_Array::make(_tpid,this).element_size());
sos_Typed_id tpid;
sos_Char c[SOS_TYPED_ID_SIZE];
sos_Object_Array::make(_tpid,this).container().read (act_pos, SOS_TYPED_ID_SIZE, c);
bcopy_to_sos_Typed_id (&tpid, c);
sos_Object o = sos_Object::make (tpid);
TT (agg_H, T_LEAVE; TI(act_pos));
return o;
} // ** get_nth **
// **************************************************************************
void _sos_Object_Array::set_nth (sos_Typed_id &_tpid,Index pos, sos_Object o)
// **************************************************************************
{
T_PROC ("sos_Object_Array::set_nth");
TT (agg_H, T_ENTER; TI (pos));
if ((pos < sos_Object_Array::make(_tpid,this).get_bottom()) OR (pos > sos_Object_Array::make(_tpid,this).get_top()))
{ err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::set_nth", FALSE);
TT (agg_H, T_LEAVE );
return;
}
sos_Offset act_pos = sos_Object_Array::make(_tpid,this).get_address() +
((pos - sos_Object_Array::make(_tpid,this).get_bottom()) * sos_Object_Array::make(_tpid,this).element_size());
sos_Typed_id tpid = o.typed_id();
sos_Char c[SOS_TYPED_ID_SIZE];
bcopy_from_sos_Typed_id (&tpid, c);
sos_Object_Array::make(_tpid,this).container().write (act_pos, SOS_TYPED_ID_SIZE, c);
TT (agg_H, T_LEAVE; TI(act_pos));
} // ** set_nth **
// **************************************************************************
void _sos_Object_Array::shift (sos_Typed_id &_tpid,Index start, sos_Int number)
// **************************************************************************
{
// Inclusively the specified 'start' element, all elements of the Array
// will be shifted 'number' elements.
// The direction depends on the sign: + means right, - means left.
// 'number' elements left from 'start' will be overwritten!
// The value of the last 'number' elements in the Array is undefined!
T_PROC ("sos_Object_Array::shift");
TT (agg_H, T_ENTER; TI (start); TI (number));
Index b = sos_Object_Array::make(_tpid,this).get_bottom();
Index t = sos_Object_Array::make(_tpid,this).get_top();
if ((start < b) OR (start > sos_Object_Array::make(_tpid,this).get_top()))
{ err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::shift()", FALSE);
TT (agg_H, T_LEAVE );
return;
}
Index goal = start + number;
if ((goal < b) OR (goal > t))
{ err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::shift()", FALSE);
TT (agg_H, T_LEAVE );
return;
}
sos_Offset a = sos_Object_Array::make(_tpid,this).get_address();
sos_Int size = sos_Object_Array::make(_tpid,this).element_size();
sos_Offset from_pos = a + sos_Offset ((start - b) * size);
sos_Offset to_pos = a + sos_Offset ((goal - b) * size);
sos_Int slice_length;
if (goal > start)
slice_length = t - goal + 1;
else
slice_length = t - start + 1;
sos_Object_Array::make(_tpid,this).container().copy (from_pos, slice_length * size,
sos_Object_Array::make(_tpid,this).container(), to_pos);
// copy takes care of the correct moving of Bytes in a container!
TT (agg_H, T_LEAVE);
} // ** shift **
// **************************************************************************
void _sos_Object_Array::rotate (sos_Typed_id &_tpid,sos_Int number)
// **************************************************************************
{
T_PROC ("sos_Object_Array::rotate");
TT (agg_H, T_ENTER; TI (number));
sos_Int crd = sos_Object_Array::make(_tpid,this).card();
if (crd == 0)
{ TT (agg_H, T_LEAVE);
return;
}
Index bottom = sos_Object_Array::make(_tpid,this).get_bottom();
Index top = sos_Object_Array::make(_tpid,this).get_top();
sos_Object o;
sos_Int i;
// Very inefficient but simple
// implementation!
if (number > 0) // rotate right
for (i = number MOD crd; i > 0; i--)
{ o = sos_Object_Array::make(_tpid,this).get_nth (top);
sos_Object_Array::make(_tpid,this).shift (bottom, 1);
sos_Object_Array::make(_tpid,this).set_nth (bottom, o);
} // for
else
for (i = (-number) MOD crd; i > 0; i--)
{ o = sos_Object_Array::make(_tpid,this).get_nth (bottom);
sos_Object_Array::make(_tpid,this).shift (bottom+1, -1);
sos_Object_Array::make(_tpid,this).set_nth (top, o);
} // for
TT (agg_H, T_LEAVE);
} // ** rotate **
// **************************************************************************
sos_Object _sos_Object_Array::__index (sos_Typed_id &_tpid,Index i)
// **************************************************************************
{
T_PROC ("sos_Object_Array::operator[]");
TT (agg_H, T_ENTER);
sos_Object o = sos_Object_Array::make(_tpid,this).get_nth (i);
TT (agg_H, T_LEAVE);
return o;
} // ** operator[] **
// **************************************************************************
Index _sos_Object_Array::current_pos (sos_Typed_id &_tpid,sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_Array::current_pos");
TT (agg_H, T_ENTER);
if (NOT sos_Object_Array::make(_tpid,this).is_valid (c))
{ err_raise (err_USE, err_AGG_WRONG_CURSOR, "sos_Object_Array::current_pos()", FALSE);
TT (agg_H, T_LEAVE );
return (0);
}
Index pos = sos_Array_node::make (c.get_current()).get_index();
TT (agg_H, T_LEAVE; TI (pos));
return pos;
} // ** current_pos **
// **************************************************************************
sos_Bool _sos_Object_Array::move_cursor (sos_Typed_id &_tpid,sos_Cursor c, Index pos)
// **************************************************************************
{
T_PROC ("sos_Object_Array::move_cursor");
TT (agg_H, T_ENTER; TI (pos));
if (NOT c.defined_for (sos_Object_Array::make(_tpid,this)))
{ err_raise (err_USE, err_AGG_WRONG_CURSOR, "sos_Object_Array::move_cursor()", FALSE);
TT (agg_H, T_LEAVE );
return (FALSE);
}
if ((pos < sos_Object_Array::make(_tpid,this).get_bottom()) OR (pos > sos_Object_Array::make(_tpid,this).get_top()))
{ err_raise (err_USE, err_AGG_ARRAY_POS_INVALID, "sos_Object_Array::move_cursor()", FALSE);
TT (agg_H, T_LEAVE );
return (FALSE);
}
sos_Array_node::make (c.get_current()).set_index (pos);
TT (agg_H, T_LEAVE);
return TRUE; // invalid positions 'pos' cause an error!
} // ** move_cursor **
// **************************************************************************
sos_Int _sos_Object_Array::size(sos_Typed_id &_tpid)
// **************************************************************************
{ T_PROC ("sos_Object_Array::size");
TT (agg_H, T_ENTER);
sos_Int sz = sos_Object_Array::make(_tpid,this).container().rounded (sos_Object_Array::make(_tpid,this).card() * SOS_TYPED_ID_SIZE) +
_sos_Object::size(_tpid);
TT (agg_H, T_LEAVE);
return sz;
} // * size **
// **************************************************************************
void _sos_Object_Array::local_assign (sos_Object_Array x, sos_Object o)
// **************************************************************************
{
// This function copies the contents of its argument onto
// the contents of (x).
// If (x) is larger than the argument, then only the first
// array_obj.card bytes are overwritten.
// If (x) is smaller than the argument, then only the first
// x.card bytes are copied.
T_PROC ("sos_Object_Array::local_assign");
TT (agg_H, T_ENTER);
sos_Object_Array y = sos_Object_Array::make (o);
Index data_size;
Index y_crd = y.card();
Index x_crd = x.card();
sos_Int size = x.element_size();
if (x_crd < y_crd)
data_size = x_crd * size;
else
data_size = y_crd * size;
Index data_begin_of_x = x.get_address();
Index data_begin_of_y = y.get_address();
y.container().copy (data_begin_of_y, data_size,
x.container(), data_begin_of_x);
TT (agg_H, T_LEAVE; TI(data_begin_of_y); TI(data_size);
TI(data_begin_of_x));
} // ** local_assign **
// **************************************************************************
sos_Bool _sos_Object_Array::local_equal (sos_Object_Array x,
sos_Object o,
sos_Eq_kind eq_kind)
// **************************************************************************
{
T_PROC ("sos_Object_Array::local_equal");
TT (agg_H, T_ENTER );
sos_Bool result;
if ((eq_kind EQ EQ_STRONG AND NOT o.has_type(x.type())) OR
(eq_kind EQ EQ_WEAK AND NOT o.isa (x.type())))
result = FALSE;
else
{ sos_Int c = x.card();
sos_Object_Array y = sos_Object_Array::make (o);
if (c != y.card())
result = FALSE;
else
{ result = TRUE;
sos_Bool based_on_equal = x.get_based_on_equal();
Index b1 = x.get_bottom();
Index b2 = y.get_bottom();
sos_Object o1, o2;
for ( ; c>0 AND result; b1++, b2++, c--)
{ o1 = x.get_nth (b1);
o2 = y.get_nth (b2);
result = agg_same_entity (o1, o2, based_on_equal, eq_kind);
}
}
}
TT (agg_H, T_LEAVE);
return result;
} // ** local_equal **
// **************************************************************************
sos_Int _sos_Object_Array::local_hash_value (sos_Object_Array x)
// **************************************************************************
{
T_PROC ("sos_Object_Array::local_hash_value");
TT (agg_H, T_ENTER );
sos_Int result;
if (x.is_empty())
result = 0;
else
result = x.get_nth (x.get_bottom()).hash_value() ^
x.get_nth (x.get_top()).hash_value();
TT (agg_H, T_LEAVE);
return result;
} // ** local_hash_value **
// **************************************************************************
sos_Object _sos_Object_Array::get (sos_Typed_id &_tpid,sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_Array::get");
TT (agg_H, T_ENTER);
if (NOT sos_Object_Array::make(_tpid,this).is_valid (c))
{ err_raise (err_USE, err_AGG_CURSOR_POS_INVALID, "sos_Object_Array::get()", FALSE);
TT (agg_H, T_LEAVE);
return (NO_OBJECT);
}
sos_Object o = sos_Object_Array::make(_tpid,this).get_nth (sos_Object_Array::make(_tpid,this).current_pos (c));
TT (agg_H, T_LEAVE);
return (o);
} // ** get **
// **************************************************************************
void _sos_Object_Array::set (sos_Typed_id &_tpid,sos_Cursor c, sos_Object o)
// **************************************************************************
{
T_PROC ("sos_Object_Array::set");
TT (agg_H, T_ENTER);
if (NOT sos_Object_Array::make(_tpid,this).is_valid (c))
{ err_raise (err_USE, err_AGG_CURSOR_POS_INVALID, "sos_Object_Array::set()", FALSE);
TT (agg_H, T_LEAVE);
return;
}
sos_Object_Array::make(_tpid,this).set_nth (sos_Object_Array::make(_tpid,this).current_pos (c), o);
TT (agg_H, T_LEAVE);
} // ** set **
// **************************************************************************
void _sos_Object_Array::remove_at (sos_Typed_id &_tpid,sos_Cursor c)
// **************************************************************************
{
// The current element, identified by the sos_Cursor c will be
// removed from the Array. This means in this case, that
// it will be replaced by NO_OBJECT. The operation returns the removed
// object. After this operation, get(c) will return the next
// element in the aggregate
T_PROC ("sos_Object_Array::remove_at");
TT (agg_H, T_ENTER);
if (NOT sos_Object_Array::make(_tpid,this).is_valid (c))
{ err_raise (err_USE, err_AGG_CURSOR_POS_INVALID, "sos_Object_Array::remove_at()", FALSE);
TT (agg_H, T_LEAVE);
}
sos_Object_Array::make(_tpid,this).set (c, NO_OBJECT);
sos_Object_Array::make(_tpid,this).to_succ (c);
TT (agg_H, T_LEAVE);
} // ** remove_at **
// **************************************************************************
sos_Int _sos_Object_Array::card (sos_Typed_id &_tpid)
// **************************************************************************
{
T_PROC ("sos_Object_Array::card");
TT (agg_H, T_ENTER);
sos_Int crd = sos_Object_Array::make(_tpid,this).get_top_index() - sos_Object_Array::make(_tpid,this).get_bottom_index() + 1;
if (crd<0) crd=0;
TT (agg_H, T_LEAVE);
return crd;
} // ** card **
// **************************************************************************
sos_Cursor _sos_Object_Array::open_cursor (sos_Typed_id &_tpid,sos_Container ct)
// **************************************************************************
{
// creates a new cursor-object and positions it
// to the first element
T_PROC ("sos_Object_Array::open_cursor");
TT (agg_H, T_ENTER);
sos_Cursor new_c = sos_Cursor::create (ct, sos_Object_Array::make(_tpid,this));
sos_Array_node new_an = sos_Array_node::create (ct);
new_an.set_index (sos_Object_Array::make(_tpid,this).get_bottom());
new_c.set_current (new_an);
sos_Object_Array::make(_tpid,this).to_first (new_c);
TT (agg_H, T_LEAVE);
return new_c;
} // ** open_cursor **
// **************************************************************************
void _sos_Object_Array::close_cursor (sos_Typed_id &_tpid,sos_Cursor c)
// **************************************************************************
{
// The result of any operation using sos_Cursor c
// is undefined after this operation.
T_PROC ("sos_Object_Array::close_cursor");
TT (agg_H, T_ENTER);
if (NOT c.defined_for (sos_Object_Array::make(_tpid,this)))
{ err_raise (err_USE, err_AGG_WRONG_CURSOR, NULL, FALSE);
TT (agg_H, T_LEAVE);
return;
}
c.get_current().destroy();
c.destroy();
TT (agg_H, T_LEAVE);
} // ** close_cursor **
// **************************************************************************
sos_Cursor _sos_Object_Array::duplicate (sos_Typed_id &_tpid,sos_Cursor c)
// **************************************************************************
{
// creates a new cursor-object for the Aggregate and
// positions it to the same element as c
T_PROC ("sos_Object_Array::duplicate");
TT (agg_H, T_ENTER);
if (NOT c.defined_for(sos_Object_Array::make(_tpid,this)))
{ err_raise (err_USE, err_AGG_WRONG_CURSOR, NULL, FALSE);
TT (agg_H, T_LEAVE);
return (sos_Cursor::make (NO_OBJECT));
}
sos_Cursor new_c = sos_Cursor::create (c.container(), sos_Object_Array::make(_tpid,this));
sos_Array_node new_an = sos_Array_node::create (c.container());
new_an.set_index (sos_Object_Array::make(_tpid,this).get_bottom());
new_c.set_current (new_an);
TT (agg_H, T_LEAVE);
return new_c;
} // ** duplicate **
// **************************************************************************
sos_Bool _sos_Object_Array::is_valid (sos_Typed_id &_tpid,sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_Array::is_valid");
TT (agg_H, T_ENTER);
Index i = sos_Array_node::make (c.get_current()).get_index();
sos_Bool valid = (sos_Bool) (i <= sos_Object_Array::make(_tpid,this).get_top() AND i >= sos_Object_Array::make(_tpid,this).get_bottom());
TT (agg_H, T_LEAVE; TB(valid));
return valid;
} // ** is_valid **
// **************************************************************************
sos_Bool _sos_Object_Array::to_first (sos_Typed_id &_tpid,sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_Array::to_first");
TT (agg_H, T_ENTER);
Index new_i = sos_Object_Array::make(_tpid,this).get_bottom();
sos_Bool valid = (sos_Bool) (new_i <= sos_Object_Array::make(_tpid,this).get_top());
sos_Array_node::make (c.get_current()).set_index (new_i);
TT (agg_H, T_LEAVE; TB(valid));
return (valid);
} // ** to_first **
// **************************************************************************
sos_Bool _sos_Object_Array::to_last (sos_Typed_id &_tpid,sos_Cursor c)
// **************************************************************************
{
T_PROC ("sos_Object_Array::to_last");
TT (agg_H, T_ENTER);
Index new_i = sos_Object_Array::make(_tpid,this).get_top();
sos_Bool valid = (sos_Bool) (new_i <= sos_Object_Array::make(_tpid,this).get_bottom());
sos_Array_node::make (c.get_current()).set_index (new_i);
TT (agg_H, T_LEAVE; TB(valid));
return (valid);
} // ** to_last **
// **************************************************************************
sos_Bool _sos_Object_Array::to_succ (sos_Typed_id &_tpid,sos_Cursor c, sos_Int i)
// **************************************************************************
{
T_PROC ("sos_Object_Array::to_succ");
TT (agg_H, T_ENTER; TI (i));
sos_Array_node an = sos_Array_node::make (c.get_current());
Index new_i = an.get_index() + i;
sos_Bool valid = (sos_Bool) (new_i <= sos_Object_Array::make(_tpid,this).get_top());
an.set_index (new_i);
TT (agg_H, T_LEAVE; TB(valid));
return (valid);
} // ** to_succ **
// **************************************************************************
sos_Bool _sos_Object_Array::to_pred (sos_Typed_id &_tpid,sos_Cursor c, Index i)
// **************************************************************************
{
// Move the sos_Cursor to the previous i-th element
// The function returns FALSE if no such element exists.
T_PROC ("sos_Object_Array::to_pred");
TT (agg_H, T_ENTER; TI (i));
sos_Array_node an = sos_Array_node::make (c.get_current());
Index new_i = an.get_index() - i;
sos_Bool valid = (sos_Bool) (new_i <= sos_Object_Array::make(_tpid,this).get_bottom());
an.set_index (new_i);
TT (agg_H, T_LEAVE; TB(valid));
return (valid);
} // ** to_pred **